package org.cjstudio.holypoopsgrs_protytpe;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.cjstudio.holypoopsgrs_interface.game.model.HolyPoopsLeaderboard;
import org.cjstudio.holypoopsgrs_interface.game.model.HolyPoopsPersonalRecord;
import org.cjstudio.holypoopsgrs_protytpe.resource.Resources.HolyPoopsResources.Leaderboard;
import org.cjstudio.holypoopsgrs_protytpe.resource.Resources.HolyPoopsResources.PersonalRecord;
import org.cjstudio.holypoopsgrs_protytpe.resource.Resources.Scoreboard.ScoreEntry;
import org.cjstudio.holypoopsgrs_protytpe.resource.Resources.Scoreboard.ScoreboardResource;
import org.cjstudio.holypoopsgrs_protytpe.resource.Resources.UserProfileBook.UserProfile;
import org.cjstudio.holypoopsgrs_protytpe.resource.Resources.UserProfileBook.UserProfileResource;
import org.cjstudio.holypoopsgrs_protytpe.resource.ScoreboardResourceMySQLImpl;
import org.cjstudio.holypoopsgrs_protytpe.resource.UserProfileResourceMySQLImpl;

@Path("holypoops")
public class HolyPoops {

	// TODO AUTOWIRE!!
	private static final UserProfileResource userProfileResource = new UserProfileResourceMySQLImpl();
	private static final ScoreboardResource scoreboardResource = new ScoreboardResourceMySQLImpl();

	@GET
	@Path("leaderboard/{type}")
	@Produces(MediaType.APPLICATION_JSON)
	public Leaderboard getLeaderboard(
			@PathParam(HolyPoopsLeaderboard.NAME_TYPE) String type, 
			@HeaderParam(HolyPoopsLeaderboard.NAME_LIMIT) Integer limit,
			@HeaderParam(HolyPoopsLeaderboard.NAME_KEY) String key) {

		/* Log */
		System.out.println("HolyPoopsServlet: holypoops/leaderboard/" + type);
		System.out.println("Type : " + type);
		System.out.println("Limit : " + limit);
		System.out.println("Key : " + key);

		//key
		
		List<ScoreEntry> entries = scoreboardResource.getLeaderEntries(limit);
		List<Long> ids = new ArrayList<Long>();
		for(ScoreEntry entry : entries)  ids.add(entry.getId());
		Map<Long, UserProfile> profiles = userProfileResource.getUserProfiles(ids);
		Leaderboard leaderboard = new Leaderboard(type, entries, profiles);
		return leaderboard;
	}

	@GET
	@Path("record/{key}")
	@Produces(MediaType.APPLICATION_JSON)
	public PersonalRecord getPersonalRecord(
			@PathParam(HolyPoopsPersonalRecord.NAME_KEY) String key) {

		/* Log */
		System.out.println("HolyPoopsServlet: holypoops/record/" + key);
		System.out.println("Key : " + key);

		//key
		
		UserProfile profile = userProfileResource.getUserProfileByKey(key);
		ScoreEntry entry = scoreboardResource.getRankedScoreEntry(profile.getId());
		PersonalRecord record = new PersonalRecord(entry, profile);
		return record;
	}

	@POST
	@Path("record/{key}")
	@Produces(MediaType.APPLICATION_JSON)
	public PersonalRecord setPersonalRecord(
			@PathParam(HolyPoopsPersonalRecord.NAME_KEY) String key,  
			@HeaderParam(HolyPoopsPersonalRecord.NAME_SCORE) Integer score) {

		/* Log */
		System.out.println("HolyPoopsServlet: holypoops/record/" + key);
		System.out.println("Key : " + key);
		System.out.println("Score : " + score);
		
		//key
		
		UserProfile profile = userProfileResource.getUserProfileByKey(key);
		ScoreEntry entry = scoreboardResource.updateScoreThenGetRankedScoreEntry(profile.getId(), score);
		PersonalRecord record = new PersonalRecord(entry, profile);
		return record;
	}
	
	@POST
	@Path("record/{key}")
	@Produces(MediaType.APPLICATION_JSON)
	public PersonalRecord setPersonalRecord(
			@PathParam(HolyPoopsPersonalRecord.NAME_KEY) String key, 
			@HeaderParam(HolyPoopsPersonalRecord.NAME_NAME) String name) {

		/* Log */
		System.out.println("HolyPoopsServlet: holypoops/record/" + key);
		System.out.println("Key : " + key);
		System.out.println("Name : " + name);

		//key
		
		Long id = userProfileResource.getUserId(key);
		UserProfile profile = userProfileResource.setNameThenGetUserProfile(id, name);
		ScoreEntry entry = scoreboardResource.getRankedScoreEntry(id);
		PersonalRecord record = new PersonalRecord(entry, profile);
		return record;
	}

}
